package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	clusterapi "github.com/louloulin/dataflare/pkg/cluster"
	"github.com/louloulin/dataflare/pkg/cluster/protoactor"
	"github.com/louloulin/dataflare/pkg/workflow/distributed"
)

func main() {
	// Parse command-line flags
	nodeID := flag.String("id", "", "Node ID (generated if not provided)")
	nodeName := flag.String("name", "", "Node name (defaults to hostname)")
	bindAddr := flag.String("bind", "0.0.0.0:7946", "Bind address")
	advertiseAddr := flag.String("advertise", "", "Advertise address (defaults to bind address)")
	seedNodes := flag.String("seeds", "", "Comma-separated list of seed nodes")
	httpAddr := flag.String("http", "0.0.0.0:8080", "HTTP server address")
	flag.Parse()

	// Generate node name if not provided
	if *nodeName == "" {
		hostname, err := os.Hostname()
		if err != nil {
			log.Fatalf("Failed to get hostname: %v", err)
		}
		*nodeName = hostname
	}

	// Parse seed nodes
	var seeds []string
	if *seedNodes != "" {
		seeds = strings.Split(*seedNodes, ",")
	}

	// Create cluster configuration
	config := clusterapi.DefaultConfig()
	config.NodeID = *nodeID
	config.BindAddress = *bindAddr
	config.AdvertiseAddress = *advertiseAddr
	config.SeedAddresses = seeds
	config.Role = "worker"
	config.Tags = []string{"dataflare", "workflow"}
	config.Metadata = map[string]string{
		"name": *nodeName,
	}

	// Create cluster manager
	manager, err := clusterapi.NewManager("protoactor", config)
	if err != nil {
		log.Fatalf("Failed to create cluster manager: %v", err)
	}

	// Start cluster manager
	ctx := context.Background()
	err = manager.Start(ctx)
	if err != nil {
		log.Fatalf("Failed to start cluster manager: %v", err)
	}
	defer manager.Stop(ctx)

	// Join cluster if seed nodes provided
	if len(seeds) > 0 {
		err = manager.Join(ctx, seeds)
		if err != nil {
			log.Fatalf("Failed to join cluster: %v", err)
		}
	}

	// Create distributed workflow server
	server, err := distributed.NewServer(manager)
	if err != nil {
		log.Fatalf("Failed to create distributed workflow server: %v", err)
	}

	// Start distributed workflow server
	err = server.Start(*httpAddr)
	if err != nil {
		log.Fatalf("Failed to start distributed workflow server: %v", err)
	}
	defer server.Stop()

	// Get local node info
	localNode, err := manager.GetLocalNode(ctx)
	if err != nil {
		log.Fatalf("Failed to get local node info: %v", err)
	}

	// Print node info
	fmt.Printf("DataFlare node started:\n")
	fmt.Printf("  Node ID: %s\n", localNode.ID)
	fmt.Printf("  Node Address: %s\n", localNode.Address)
	fmt.Printf("  HTTP Server: http://%s\n", *httpAddr)
	fmt.Printf("  Role: %s\n", localNode.Role)
	fmt.Printf("  Tags: %v\n", localNode.Tags)
	fmt.Printf("  Started: %s\n", localNode.StartTime.Format(time.RFC3339))

	// Wait for interrupt signal
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh

	fmt.Println("Shutting down...")
}
